package com.lora.websocket;

import com.acooly.core.utils.Strings;
import com.lora.websocket.message.WebSockerSender;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
@ServerEndpoint("/websocket/{empId}")
public class WebSocketServer {

	@Resource
	private WebSockerSender socketMessageHelper;
	/**在线人数*/
	private static volatile Integer ONLINE_COUNT = 0;
	/**在线socket集合*/
	private static final Map<String, Session> SOCKET_MAP = new ConcurrentHashMap<>();
	
	/**
	 * 连接建立成功
	 */
	@OnOpen
	public void onOpen(@PathParam("empId") String empId, Session session) {
		//socketMessageHelper.loginoutSend(empId, WebSocketMessageHelper.MSG_TYPE_LOGIN);
		SOCKET_MAP.put(empId, session);
		addOnlineCount();
		log.info("用户登录empid={}，当前在线:{}人，分别是：{}", empId, ONLINE_COUNT, SOCKET_MAP.keySet());
	}

	/**
	 * 连接关闭
	 */
	@OnClose
	public void onClose(@PathParam("empId") String empId) {
		//socketMessageHelper.loginoutSend(empId, WebSocketMessageHelper.MSG_TYPE_LOGOUT);
		SOCKET_MAP.remove(empId);
		subOnlineCount();
		log.info("用户退出empid={}，当前在线:{}人，分别是：{}", empId, ONLINE_COUNT, SOCKET_MAP.keySet());
	}
	
	/**
	 * 收到客户端消息后调用的方法
	 */
	@OnMessage
	public void onMessage(@PathParam("empId") Long empId, String message) {
		System.out.println(message);
	}

	/**
	 * 发生错误
	 */
	@OnError
	public void onError(
			@PathParam("empId") Long empId, 
			Session session, 
			Throwable error) {
		log.error("发生错误,empId={},errorMsg={}!", empId, error.getMessage());
		//socketMessageHelper.loginoutSend(empId, WebSocketMessageHelper.MSG_TYPE_LOGOUT);
	}

	/**
	 * 发送消息给所有人
	 */
	public static void sendMessageToAll(String message) {
		for (Session session : SOCKET_MAP.values()) {
			sendMessage(session, message);
		}
	}
	
	/**
	 * 发送消息到指定客户端
	 * @return 
	 */
	public static boolean sendMessage(Long empId, String message) {
		if (SOCKET_MAP.containsKey(empId)){
			return sendMessage(SOCKET_MAP.get(empId), message);
		} else {
			return false;
		}
	}
	
	/**
	 * 发送消息到指定客户端
	 * @return 
	 */
	public static boolean sendMessage(Session session, String message) {
		if (Strings.isEmpty(message)) {
			log.error("服务器发送了一个空消息被截获！！！");
			return false;
		}
		if (session == null || !session.isOpen()) {
			log.error("目标客户端为空或者目标websocket已关闭！");
			return false;
		}
		try {
			session.getBasicRemote().sendText(message);
			return true;
		} catch (Exception e) {
			log.error("服务器发送消息时出现异常！！！errorMsg={}", e.getMessage());
			return false;
		}
	}

	public static synchronized int getOnlineCount() {
		return WebSocketServer.ONLINE_COUNT;
	}

	public static synchronized void addOnlineCount() {
		WebSocketServer.ONLINE_COUNT++;
	}

	public static synchronized void subOnlineCount() {
		if (WebSocketServer.ONLINE_COUNT == 0) {
			log.info("帐号退出异常!");
		} else {
			WebSocketServer.ONLINE_COUNT--;
		}
	}
}
